﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Utils;
using Log;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Globalization;
using System.Media;
using System.Drawing.Drawing2D;

namespace AutoTrader
{
    public partial class AutoTraderForm : Form
    {
        private LogString myLogger = LogString.GetLogString( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
        private delegate void UpdateDelegate();
        DateTime __DATE__ = File.GetLastWriteTime(Application.ExecutablePath);
        DSAPI_Client.clientAPI obj = new DSAPI_Client.clientAPI();
        string strExtNumber;

        Font fontBold = new Font( "Microsoft Sans Serif", 7.47f, FontStyle.Bold );
        Font fontRegular = new Font( "Microsoft Sans Serif", 7.47f, FontStyle.Regular );

        private void LogUpdate()
        {
            Invoke(new UpdateDelegate(
                    delegate
                    {
                        listBox.BeginUpdate();
                        if (listBox.Items.Count >= 2048)
                            listBox.Items.RemoveAt(0);
                        listBox.Items.Add(myLogger.Log);
                        listBox.SetSelected(listBox.Items.Count - 1, true);
                        listBox.SetSelected(listBox.Items.Count - 1, false);
                        listBox.EndUpdate();
                        Debug.WriteLine(myLogger.Log);
                    })
                );
        }

        public AutoTraderForm()
        {
            InitializeComponent();

            if (!ReadSetSettings())
            {
                btStart.Enabled = false;
                btStop.Enabled = false;
                btExit.Enabled = true;
            }

            Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
            Debug.AutoFlush = true;
            Debug.Indent();

            string dateStr = __DATE__.ToString("yyyy.MM.dd HH:mm:ss");
            this.Text = "FlameSoft AutoTrader ver. 1.01 " + dateStr;
            myLogger.OnLogUpdate += new LogString.LogUpdateDelegate(this.LogUpdate);
            backgroundGetQuotes.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundGetQuotes_Completed);
            myLogger.LogCreate();
            btStop.Enabled = false;
            btClosePos.Enabled = false;
            bClosePosition = false;
            textClientNumber.Text = Settings.Settings.ClientNumber;
            cbInstruments.SelectedItem = (object)Settings.Settings.Instrument;
            this.timer.Start();
        }

        private void btStart_Click(object sender, EventArgs e)
        {
            myLogger.Add("Button START Pressed!");
            strExtNumber = textClientNumber.Text;

            GetSaveSettings();

            //if (!backgroundGetQuotes.IsBusy)
            if (!backgroundTrader.IsBusy)
            {
//                backgroundGetQuotes.RunWorkerAsync();
                backgroundTrader.RunWorkerAsync();
                btStart.Enabled = false;
                btStop.Enabled = true;
                btExit.Enabled = false;
                cbInstruments.Enabled = false;
                textClientNumber.Enabled = false;
                cbInitialLots.Enabled = false;
                cbMaxDouble.Enabled = false;
                cbPipsStep.Enabled = false;
                chSmartStep.Enabled = false;
                chAutoStart.Enabled = false;
            }
            else
            {
                myLogger.Add("BackgroundWorker is Busy. Try again.");
            }
        }

        private void btStop_Click(object sender, EventArgs e)
        {
            myLogger.Add("Button STOP Pressed!");
            //if (backgroundGetQuotes.WorkerSupportsCancellation == true)
            if (backgroundTrader.WorkerSupportsCancellation == true)
            {                
                //backgroundGetQuotes.CancelAsync();
                backgroundTrader.CancelAsync();
            }
            else
            {
                myLogger.Add("Worker Cancellation not supported!");
            }
            this.timer.Stop();
        }

        private void btExit_Click(object sender, EventArgs e)
        {
            GetSaveSettings();
            myLogger.Add("Button EXIT Pressed!");
            if (DialogResult.Yes == MessageBoxEx.Show(this.listBox, "Do you really want to exit?", "AutoTrader",
                                                             MessageBoxButtons.YesNo, MessageBoxIcon.Question))
            {
                myLogger.Add("Application Exited!");
                Settings.Settings.Save();
                this.Close();
            }
        }

        private void DrawTitle(Graphics g)
        {
            Font f = new Font("Times New Roman", 20, FontStyle.Bold);
            Brush b = new LinearGradientBrush(new Point(1, 1), new Point(300, 300), Color.Blue, Color.Black);
            g.DrawString("FlameSoft AutoTrader Utility", f, b, 5, 5);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics dc = e.Graphics;
            if (e.ClipRectangle.Top < 350 || e.ClipRectangle.Left < 250)
            {
                DrawTitle(dc);
            }
            base.OnPaint(e);
        }

        private void AutoTraderForm_Load(object sender, EventArgs e)
        {
            myLogger.Add(this.Text + " - Program started.");
        }

        private void backgroundGetQuotes_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            btStart.Enabled = true;
            btStop.Enabled = false;
            btExit.Enabled = true;
            cbInstruments.Enabled = true;
            textClientNumber.Enabled = true;
            cbInitialLots.Enabled = true;
            cbMaxDouble.Enabled = true;
            cbPipsStep.Enabled = true;
            chSmartStep.Enabled = true;
            chAutoStart.Enabled = true;
        }

        private void backgroundGetQuotes_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //this.progressBar1.Value = e.ProgressPercentage;
            txtBuy.Text = BuyPrice.ToString();
            txtSell.Text = SellPrice.ToString();

            txtBaseOrder.Text = BaseOrder.ID.ToString();
            txtBaseLots.Text = BaseOrder.Lots.ToString();
            txtBaseBuyOrSell.Text = BaseOrder.BuyOrSell;
            txtBasePrice.Text = BaseOrder.Price.ToString();

            txtStopOrder.Text = StopOrder.ID.ToString();
            txtStopLots.Text = StopOrder.Lots.ToString();
            txtStopBuyOrSell.Text = StopOrder.BuyOrSell;
            txtStopPrice.Text = StopOrder.Price.ToString();
            lblTotalResult.Text = string.Format("Total Result: {0} {1}", dResultAll.ToString("F3", CultureInfo.InvariantCulture), Settings.Settings.Instrument.Substring(4, 3));

            if (StopOrder.ID > 0)
                btClosePos.Enabled = true;
            else
                btClosePos.Enabled = false;

            int value = e.ProgressPercentage;
            decimal top = 0.0m;
            progressBar.Value = value;
            lblStop.Text = string.Format( "Stop at {0}", StopOrder.Price.ToString() );            

            if (BaseOrder.BuyOrSell == "1")// sell
            {
                top = StopOrder.Price - 2*PipsStep - PipsStep*0.2m;
                lblSell.Font = fontBold;
                lblBuy.Font = fontRegular;
            }
            else
            {
                top = StopOrder.Price + 2*PipsStep + PipsStep*0.2m;
                lblSell.Font = fontRegular;
                lblBuy.Font = fontBold;
            }
            lblReorder.Text = string.Format("Reorder at {0}", top.ToString());
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (Settings.Settings.AutoStart == "True")        
                btStart_Click(this, null);
            this.timer.Stop();
        }

        private void btClosePos_Click(object sender, EventArgs e)
        {
            myLogger.Add("Button CLOSE Pressed!");
            bClosePosition = true;
        } 
    }
}
